-use std::io::{timer, fs, File};
-use std::io::fs::PathExtensions;
+use std::io::fs;
+use std::io::{timer, File};
use std::time::Duration;
+use git2;
-use support::{ProjectBuilder, ResultTest, project, execs, main_file, paths};
+use support::{ProjectBuilder, ResultTest, project, execs, main_file};
use support::{cargo_dir, path2url};
use support::{COMPILING, UPDATING, RUNNING};
use support::paths::PathExt;
fn git_repo(name: &str, callback: |ProjectBuilder| -> ProjectBuilder)
-> Result<ProjectBuilder, ProcessError>
{
- let gitconfig = paths::home().join(".gitconfig");
-
- if !gitconfig.exists() {
- File::create(&gitconfig).write(r"
- [user]
-
- email = foo@bar.com
- name = Foo Bar
- ".as_bytes()).assert()
- }
-
let mut git_project = project(name);
git_project = callback(git_project);
git_project.build();
- log!(5, "git init");
- try!(git_project.process("git").args(["init", "--template="]).exec_with_output());
- log!(5, "building git project");
- log!(5, "git add .");
- try!(git_project.process("git").args(["add", "."]).exec_with_output());
- log!(5, "git commit");
- try!(git_project.process("git").args(["commit", "-m", "Initial commit"])
- .exec_with_output());
+ let repo = git2::Repository::init(&git_project.root()).unwrap();
+ let mut cfg = repo.config().unwrap();
+ cfg.set_str("user.email", "foo@bar.com").unwrap();
+ cfg.set_str("user.name", "Foo Bar").unwrap();
+ drop(cfg);
+ add(&repo);
+ commit(&repo);
Ok(git_project)
}
+fn add(repo: &git2::Repository) {
+ // FIXME(libgit2/libgit2#2514): apparently add_all will add all submodules
+ // as well, and then fail b/c they're a directory. As a stopgap, we just
+ // ignore all submodules.
+ let mut s = repo.submodules().unwrap();
+ for submodule in s.mut_iter() {
+ submodule.add_to_index(false).unwrap();
+ }
+ let mut index = repo.index().unwrap();
+ index.add_all(&["*"], git2::AddDefault, Some(|a: &[u8], _b: &[u8]| {
+ if s.iter().any(|s| s.path().as_vec() == a) {1} else {0}
+ })).unwrap();
+ index.write().unwrap();
+}
+
+fn add_submodule<'a>(repo: &'a git2::Repository, url: &str,
+ path: &Path) -> git2::Submodule<'a> {
+ let mut s = repo.submodule(url, path, false).unwrap();
+ let subrepo = s.open().unwrap();
+ let mut origin = subrepo.find_remote("origin").unwrap();
+ origin.add_fetch("refs/heads/*:refs/heads/*").unwrap();
+ origin.fetch(None, None).unwrap();
+ origin.save().unwrap();
+ subrepo.checkout_head(None).unwrap();
+ s.add_finalize().unwrap();
+ return s;
+}
+
+fn commit(repo: &git2::Repository) -> git2::Oid {
+ let tree_id = repo.index().unwrap().write_tree().unwrap();
+ let sig = repo.signature().unwrap();
+ let mut parents = Vec::new();
+ match repo.head().ok().map(|h| h.target().unwrap()) {
+ Some(parent) => parents.push(repo.find_commit(parent).unwrap()),
+ None => {}
+ }
+ let parents = parents.iter().collect::<Vec<_>>();
+ repo.commit(Some("HEAD"), &sig, &sig, "test",
+ &repo.find_tree(tree_id).unwrap(),
+ parents.as_slice()).unwrap()
+}
+
test!(cargo_compile_simple_git_dep {
let project = project("foo");
let git_project = git_repo("dep1", |project| {
"#)
}).assert();
- git_project.process("git").args(["checkout", "-b", "branchy"]).exec_with_output().assert();
- git_project.process("git").args(["checkout", "master"]).exec_with_output().assert();
+ // Make a new branch based on the current HEAD commit
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let head = repo.head().unwrap().target().unwrap();
+ let head = repo.find_commit(head).unwrap();
+ repo.branch("branchy", &head, true, None, None).unwrap();
let project = project
.file("Cargo.toml", format!(r#"
"#)
}).assert();
- git_project.process("git").args(["tag", "v0.1.0"]).exec_with_output().assert();
- git_project.process("git").args(["checkout", "-b", "tmp"]).exec_with_output().assert();
- git_project.process("git").args(["branch", "-d", "master"]).exec_with_output().assert();
+ // Make a tag correponding to the current HEAD
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let head = repo.head().unwrap().target().unwrap();
+ repo.tag("v0.1.0",
+ &repo.find_object(head, None).unwrap(),
+ &repo.signature().unwrap(),
+ "make a new tag",
+ false).unwrap();
let project = project
.file("Cargo.toml", format!(r#"
.file("src/lib.rs", "pub fn bar() -> int { 1 }")
}).assert();
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ let rev1 = repo.revparse_single("HEAD").unwrap().id().to_string();
+
// Commit the changes and make sure we trigger a recompile
- let rev1 = bar.process("git").args(["rev-parse", "HEAD"])
- .exec_with_output().assert();
File::create(&bar.root().join("src/lib.rs")).write_str(r#"
pub fn bar() -> int { 2 }
"#).assert();
- bar.process("git").args(["add", "."]).exec_with_output().assert();
- bar.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
- let rev2 = bar.process("git").args(["rev-parse", "HEAD"])
- .exec_with_output().assert();
-
- let rev1 = String::from_utf8(rev1.output).unwrap();
- let rev2 = String::from_utf8(rev2.output).unwrap();
+ add(&repo);
+ let rev2 = commit(&repo).to_string();
let foo = project("foo")
.file("Cargo.toml", format!(r#"
// Commit the changes and make sure we don't trigger a recompile because the
// lockfile says not to change
- git_project.process("git").args(["add", "."]).exec_with_output().assert();
- git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ add(&repo);
+ commit(&repo);
println!("compile after commit");
assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
File::create(&git_project.root().join("src/bar.rs")).write_str(r#"
pub fn bar() { println!("hello!"); }
"#).assert();
- git_project.process("git").args(["add", "."]).exec_with_output().assert();
- git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ add(&repo);
+ commit(&repo);
timer::sleep(Duration::milliseconds(1000));
.file("lib.rs", "pub fn dep() {}")
}).assert();
- git_project.process("git").args(["submodule", "add"])
- .arg(git_project2.root()).arg("src").exec_with_output().assert();
- git_project.process("git").args(["add", "."]).exec_with_output().assert();
- git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let url = path2url(git_project2.root()).to_string();
+ add_submodule(&repo, url.as_slice(), &Path::new("src"));
+ commit(&repo);
let project = project
.file("Cargo.toml", format!(r#"
File::create(&git1.root().join("src/lib.rs")).write_str(r#"
pub fn foo() {}
"#).assert();
- git1.process("git").args(["add", "."]).exec_with_output().assert();
- git1.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&git1.root()).unwrap();
+ add(&repo);
+ commit(&repo);
assert_that(project.process(cargo_dir().join("cargo")).arg("update").arg("dep1"),
execs()
File::create(&bar.root().join("src/lib.rs")).write_str(r#"
pub fn bar() -> int { 1 + 0 }
"#).assert();
- bar.process("git").args(["add", "."]).exec_with_output().assert();
- bar.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ add(&repo);
+ commit(&repo);
timer::sleep(Duration::milliseconds(1000));
- let rev = bar.process("git").args(["rev-parse", "HEAD"])
- .exec_with_output().assert();
- let rev = String::from_utf8(rev.output).unwrap();
+ let rev = repo.revparse_single("HEAD").unwrap().id();
File::create(&foo.root().join("Cargo.lock")).write_str(format!(r#"
[root]
.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
}).assert();
- git_project.process("git").args(["submodule", "add"])
- .arg(git_project2.url().to_string()).arg("src").exec_with_output()
- .assert();
- git_project.process("git").args(["add", "."]).exec_with_output().assert();
- git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let mut sub = add_submodule(&repo, git_project2.url().to_string().as_slice(),
+ &Path::new("src"));
+ commit(&repo);
let project = project
.file("Cargo.toml", format!(r#"
file.write_str(format!("[submodule \"src\"]\n\tpath = src\n\turl={}",
git_project3.url()).as_slice()).assert();
- git_project.process("git").args(["submodule", "sync"]).exec_with_output().assert();
- git_project.process("git").args(["fetch"]).cwd(git_project.root().join("src"))
- .exec_with_output().assert();
- git_project.process("git").args(["reset", "--hard", "origin/master"])
- .cwd(git_project.root().join("src")).exec_with_output().assert();
- git_project.process("git").args(["add", "."]).exec_with_output().assert();
- git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ // Sync the submodule and reset it to the new remote.
+ sub.sync().unwrap();
+ {
+ let subrepo = sub.open().unwrap();
+ let mut origin = subrepo.find_remote("origin").unwrap();
+ origin.set_url(git_project3.url().to_string().as_slice()).unwrap();
+ origin.add_fetch("refs/heads/*:refs/heads/*").unwrap();;
+ origin.fetch(None, None).unwrap();
+ origin.save().unwrap();
+ let id = subrepo.refname_to_id("refs/remotes/origin/master").unwrap();
+ let obj = subrepo.find_object(id, None).unwrap();
+ subrepo.reset(&obj, git2::Hard, None, None).unwrap();
+ }
+ sub.add_to_index(true).unwrap();
+ add(&repo);
+ commit(&repo);
timer::sleep(Duration::milliseconds(1000));
// Update the dependency and carry on!
"#)
}).assert();
- fs::unlink(&paths::home().join(".gitconfig")).assert();
+ let repo = git2::Repository::open(&p2.root()).unwrap();
+ let mut cfg = repo.config().unwrap();
+ let _ = cfg.remove("user.name");
+ let _ = cfg.remove("user.email");
let p = project("foo")
.file("Cargo.toml", format!(r#"
File::create(&bar.root().join("src/lib.rs")).write_str(r#"
pub fn bar() -> int { 2 }
"#).assert();
- bar.process("git").args(["add", "."]).exec_with_output().assert();
- bar.process("git").args(["commit", "-m", "test"]).exec_with_output()
- .assert();
+ let repo = git2::Repository::open(&bar.root()).unwrap();
+ add(&repo);
+ commit(&repo);
// Lock p2 to the second rev
let p2 = project("p2")